package com.roc.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.persistence.Transient;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.roc.bean.MenuBean;
import com.roc.dao.DaoException;
import com.roc.dao.IBaseDao;
import com.roc.dao.IModelDao;
import com.roc.dao.impl.BaseDaoImpl;
import com.roc.pojo.Module;
import com.roc.pojo.ModuleCategory;
import com.roc.pojo.Operators;
import com.roc.pojo.PowerModel;
import com.roc.pojo.PowerModule;
import com.roc.pojo.ProfitModule;
import com.roc.pojo.ProfitPercent;
import com.roc.pojo.ProfitPercentModule;
import com.roc.pojo.ProfitRule;
import com.roc.pojo.ProfitRuleModule;
import com.roc.service.IModelService;
import com.roc.service.ServiceException;
import com.roc.util.constant.Constant;
import com.roc.util.constant.ProfitModuleStatus;
import com.roc.util.constant.SysLogType;

@Service
@Transactional
@SuppressWarnings("all")
public class ModelServiceImpl  implements IModelService{
    static Logger logger=LogManager.getLogger(PowerInfoServiceImpl.class);
	
	@Autowired
	IModelDao modelDao;
	@Autowired
	private IBaseDao baseDao;
	
	
	@Override
	public List<ModuleCategory> queryAllModuleCategoryList()
			throws ServiceException {
		// TODO Auto-generated method stub
		List<MenuBean> menuBeanList=null;
		List<ModuleCategory> moduleCategoryList=new ArrayList<ModuleCategory>();
		Map<String,ModuleCategory> categoryMenuMap=new TreeMap<String,ModuleCategory>();
		
		try{
			menuBeanList=modelDao.listAllMenus();
			ModuleCategory temp=new ModuleCategory();
			ModuleCategory moduleCategory=null;
			
			for(MenuBean bean:menuBeanList){
				
				String moduleCotegoryCode=bean.getCategoryCode();//主菜单
				if(!moduleCotegoryCode.equals(temp.getModuleCategoryCode())){//新主菜单
					moduleCategory=new ModuleCategory();
					temp.setModuleCategoryCode(bean.getCategoryCode());
					temp.setModuleCategoryName(bean.getCategoryName());
					
					moduleCategory.setModuleCategoryCode(bean.getCategoryCode());
					moduleCategory.setModuleCategoryName(bean.getCategoryName());
					
					Module module=new Module();
					module.setModuleCode(bean.getModuleCode());
					module.setModuleName(bean.getModuleName());
					
					moduleCategory.getModules().add(module);
					categoryMenuMap.put(moduleCotegoryCode, moduleCategory);
				}else{
					Module module=new Module();
					module.setModuleCode(bean.getModuleCode());
					module.setModuleName(bean.getModuleName());
					module.setModuleAct(bean.getModuleAct());
					moduleCategory.getModules().add(module);
					
					categoryMenuMap.put(moduleCotegoryCode, moduleCategory);
				}
				
			}
			
			for(String key:categoryMenuMap.keySet()){
				moduleCategoryList.add(categoryMenuMap.get(key));
			}
			
		}catch(DaoException e){
			logger.error(e.getMessage(),e);
			throw new ServiceException("查询菜单和模块功能失败(用户权限模板)！");
		}
		return moduleCategoryList;
	}


	@Override
	public void saveModelBatch(Operators oper, List<String> list,
			PowerModel modelHead) throws ServiceException {
		// TODO Auto-generated method stub
	//	modelHead.setDtCreate(new Date());
		modelHead.setDtLostmod(new Date());
		try{
			for(String moduleCode:list){
				PowerModule tempModule=new PowerModule();
				tempModule.setModelCode(modelHead.getModelCode());
				tempModule.setModuleCode(moduleCode);
				tempModule.setOperatorsId(modelHead.getOperatorsId());
				tempModule.setDtLostmod(new Date());
				modelDao.editSave(tempModule);
			}
			modelDao.editSave(modelHead);
			baseDao.addSyslog(SysLogType.MODEL_ADD.getCode(), SysLogType.MODEL_ADD.getName(), oper.getAccountNo(), "操作员【"+oper.getAccountNo()+"】添加用户权限模板【"+modelHead.getModelName()+"】成功");
		}catch(DaoException e){
			logger.error(e.getMessage(),e);
			throw new ServiceException("保存模板出错！");
		}
		
	}


	@Override
	public List<PowerModule> queryModule(Long operatorsId,String modelCode)
			throws ServiceException {
		// TODO Auto-generated method stub
		List<PowerModule> moduleList;
		try{
			
			 moduleList=modelDao.queryModuleByOperatorId(operatorsId, modelCode);
			
		}catch(DaoException e){
			logger.error(e.getMessage(),e);
			throw new ServiceException("查询模板菜单出错！");
		}
		return moduleList;
	}


	@Override
	public PowerModel queryModelById(Long id) throws ServiceException {
		// TODO Auto-generated method stub
		PowerModel model;
		try{
			 model=(PowerModel) modelDao.loadById(id, PowerModel.class);
		}catch(DaoException e){
			logger.error(e.getMessage(),e);
			throw new ServiceException("查询唯一模板出错！");
		}
		return model;
	}


	@Override
	public boolean updateSave(PowerModel model,List<PowerModule> moduleList,Operators oper)
			throws ServiceException {
		// TODO Auto-generated method stub
		List<PowerModule> tempModuleList;
		int flag=0;
		try{
			modelDao.editUpdate(model);
			tempModuleList=modelDao.queryModuleByOperatorId(model.getOperatorsId(), model.getModelCode());
			for(PowerModule module:tempModuleList){
				flag=0;
				for(PowerModule delModule:moduleList){
					if(module.getModuleCode().equals(delModule.getModuleCode())){
						flag=1;
						break;
					}
				}
				if(flag==0){
					modelDao.delete(module);
				}
			}
			for(PowerModule module:moduleList){
				if(module.getId()==null||module.getId()==0){
					modelDao.editSave(module);
				}
			}
			modelDao.addSyslog(SysLogType.MODEL_MODIF.getCode(), SysLogType.MODEL_MODIF.getName(), oper.getAccountNo(), "操作员【"+oper.getAccountNo()+"】修改用户权限模板【"+model.getModelName()+"】成功");
			
		}catch(DaoException e){
			logger.error(e.getMessage(),e);
			throw new ServiceException("查询唯一模板出错！");
		}
		
		
		return true;
	}


	@Override
	public boolean deleteModel(PowerModel model, Operators oper)
			throws ServiceException {
		// TODO Auto-generated method stub
		List<PowerModule> moduleList;
		try{
			 moduleList=modelDao.queryModuleByOperatorId(model.getOperatorsId(), model.getModelCode());
			 modelDao.delete(model);
			 for(PowerModule del:moduleList){
				 modelDao.delete(del);
			 }
			 modelDao.addSyslog(SysLogType.MODEL_DELETE.getCode(), SysLogType.MODEL_DELETE.getName(), oper.getAccountNo(), "操作员【"+oper.getAccountNo()+"】删除了用户权限模板【"+model.getModelName()+"】");
		}catch(DaoException e){
			logger.error(e.getMessage(),e);
			throw new ServiceException("查询唯一模板出错！");
		}
		
		return true;
	}


	@Override
	public List<Object> listAllProfitModelHeads(Operators oper) throws ServiceException {
		// TODO Auto-generated method stub
		List<Object> objList=new ArrayList<Object>();
		try{
			objList=modelDao.queryAll("from PowerModel p where p.operatorsId="+oper.getId());
		}catch (DaoException e) {
			e.printStackTrace();
			throw new ServiceException("查询常用的权限模板信息出错");
		}
		return objList;
	}

	@Override
	public List<ProfitModule> queryProfitModuleByAgentId(String agentId) throws ServiceException {
		List<ProfitModule> profitModuleList = new ArrayList<ProfitModule>();
		try {
			profitModuleList = modelDao.queryProfitModuleByAgentId(agentId);
		} catch (DaoException e) {
			logger.error("######查询代理商分润模板失败######", e);
			throw new ServiceException("查询代理商分润模板失败!");
		}
		return profitModuleList;
	}

	@Override
	@Transactional(rollbackFor = { ServiceException.class })
	public void saveProfitModuleBatch(Operators oper, ProfitModule profitModule)
			throws ServiceException {
		profitModule.setDtCreate(new Date());
		profitModule.setDtLastmod(new Date());
		
		try{
			profitModule.setAgentId(oper.getId());
			profitModule.setAgentAccount(oper.getAccountNo());
			// 添加模板信息
			modelDao.editSave(profitModule);
			
			long modelId = profitModule.getId(); // 模板id
			
			// 添加MCC类别
			if (profitModule.getProList() != null && profitModule.getProList().size() > 0) {
				List<ProfitRuleModule> proList = profitModule.getProList();
				for (ProfitRuleModule profitRule : proList) {
					
					if (profitRule.getId() != null) {

						// 如果是 云闪付，判断费率是否为0.28
						if ( 5 == profitRule.getId() ){
							double profitFee = profitRule.getProfitFee() ; 
							double profitSettleRate = profitRule.getProfitSettleRate() ; 
							double merchantMinFee = profitRule.getMerchantMinFee() ; 
							
							if ( profitFee != Constant.FEE_RATE ){
								throw new ServiceException("代理申请失败，云闪付 借记卡成本扣率 只能等于 " + Constant.FEE_RATE );
							}
							if ( profitSettleRate != Constant.FEE_RATE ){
								throw new ServiceException("代理申请失败，云闪付 贷记卡成本扣率 只能等于 " + Constant.FEE_RATE );
							}
							if ( merchantMinFee != Constant.FEE_RATE ){
								throw new ServiceException("代理申请失败，云闪付 贷记卡最低签扣 只能等于 " + Constant.FEE_RATE );
							}
						}
						// 如果是 银联扫码（非优惠），判断费率是否低于0.5025
						if ( 6 == profitRule.getId() ){
							double profitFee = profitRule.getProfitFee() ; 
							
							if ( profitFee < Constant.UNIONPAY_EVERYDAY_RATE ){
								throw new ServiceException("代理申请失败，银联扫码(非优惠) 成本扣率 不能低于 " + Constant.UNIONPAY_EVERYDAY_RATE );
							}
						}
						// 如果是 银联扫码（优惠），判断费率是否低于0.2
						if ( 7 == profitRule.getId() ){
							double profitFee = profitRule.getProfitFee() ; 
							
							if ( profitFee < Constant.UNIONPAY_UNEVERYDAY_RATE ){
								throw new ServiceException("代理申请失败，银联扫码(优惠) 成本扣率 不能低于 " + Constant.UNIONPAY_UNEVERYDAY_RATE );
							}
						}
						// 如果是 支付宝微信扫码，判断费率只能是 0.25-0.35 之间
						if ( 8 == profitRule.getId() ){
							double profitFee = profitRule.getProfitFee() ; 
							
							if ( profitFee < Constant.MIN_ALIPAY_RATE || profitFee > Constant.MAX_ALIPAY_RATE ){
								throw new ServiceException("代理申请失败，支付宝微信扫码 成本扣率 只能是 " + Constant.MIN_ALIPAY_RATE +"-" + Constant.MAX_ALIPAY_RATE + " 之间 " );
							}
						}
						
						profitRule.setDtCreate (new Date());
						profitRule.setDtLastmod (new Date());
						
						profitRule.setProfitModuleId(modelId);
						modelDao.editSave(profitRule);// add分润规则
					}
				}
			}
			
			// 添加代理商分润比例
			if (profitModule.getProfitPerList() != null && profitModule.getProfitPerList().size() > 0) {
				List<ProfitPercentModule> prList = profitModule.getProfitPerList();
				// 删除空数据
				prList = dealNull(prList);
				int i = 0;
				for (ProfitPercentModule profitPercent : prList) {

					profitPercent.setDtCreate (new Date());
					profitPercent.setDtLastmod (new Date());
					
					profitPercent.setProfitModuleId(modelId);
				//	profitPercent.setAgent_id(op.getAccountNo());
					BigDecimal per = new BigDecimal(profitPercent.getPercent());
					profitPercent.setPercent(per.divide(new BigDecimal(100))
							.toString());

					if (i == 0) {
						profitPercent.setIsEnd("0");
					} else {
						profitPercent.setIsEnd("1");
					}
					if (i == prList.size() - 1) {
						profitPercent.setIsEnd("2");
					}
					modelDao.editSave(profitPercent);
					i++;
				}

			}

			logger.info("操作员【" + oper.getId() + "-" + oper.getAccountNo() + "】添加代理商分润模板【" + profitModule.getModuleName() + "】成功");
			modelDao.addSyslog(SysLogType.MODEL_PROFIT_ADD.getCode(), SysLogType.MODEL_PROFIT_ADD.getName(), oper.getAccountNo(), 
					"操作员【" + oper.getId() + "-" + oper.getAccountNo() + "】添加代理商分润模板【" + profitModule.getModuleName() + "】成功");
		}catch(DaoException e){
			logger.error(e.getMessage(),e);
			throw new ServiceException("保存分润模板出错！");
		}
	}



	public List<ProfitPercentModule> dealNull(List<ProfitPercentModule> prList) {
		List<ProfitPercentModule> newList = new ArrayList<ProfitPercentModule>();
		for (ProfitPercentModule per : prList) {
			if (!"".equals(per.getPercent().trim()) && per.getPercent() != null) {
				newList.add(per);
			}
		}
		return newList;

	}


	@Override
	public ProfitModule queryProfitModuleById(Long operatorsId, String modelId)
			throws ServiceException {
		ProfitModule module = new ProfitModule();
		try {
			module = modelDao.queryProfitModuleById(modelId);
		} catch (DaoException e) {
			logger.error("######查询代理商分润模板失败######", e);
			throw new ServiceException("查询代理商分润模板失败!");
		}
		
		return module;
	}


	@Override
	public ProfitModule queryDefProfitModuleByAgentId(long agentId) throws ServiceException {
		ProfitModule profitModule = new ProfitModule();
		try {
			profitModule = modelDao.selDefProfitModuleByAgentId( agentId);
		} catch (DaoException e) {
			logger.error("######查询代理商分润模板失败######", e);
			throw new ServiceException("查询代理商分润模板失败!");
		}
		return profitModule;
	}


	@Override
	public List<ProfitRuleModule> queryProfitRuleModule(Long operatorsId,
			String modelId) throws ServiceException {
		List<ProfitRuleModule> profitRuleModuleList = new ArrayList<ProfitRuleModule>();

		try {
			profitRuleModuleList = modelDao.queryProfitRuleModule(modelId);
		} catch (DaoException e) {
			logger.error("######查询代理商分润规则模板失败######", e);
			throw new ServiceException("查询代理商分润规则模板失败!");
		}
		
		return profitRuleModuleList;
	}


	@Override
	public List<ProfitPercentModule> queryProfitPercentModule(Long operatorsId,
			String modelId) throws ServiceException {
		List<ProfitPercentModule> profitPerModuleList = new ArrayList<ProfitPercentModule>();

		try {
			profitPerModuleList = modelDao.queryProfitPerModule(modelId);
		} catch (DaoException e) {
			logger.error("######查询代理商分润比例模板失败######", e);
			throw new ServiceException("查询代理商分润比例模板失败!");
		}
		
		return profitPerModuleList;
	}


	@Override
	@Transactional(rollbackFor = { ServiceException.class })
	public boolean updateSaveProfitModule(ProfitModule profitModule, Operators logingOperators, ProfitModule oldPro) throws ServiceException {
		boolean flag = false;
		// 查询模板是否存在
		try {
			if (profitModule != null) {// 数据库代理商信息不为空
				long modelId = profitModule.getId();

				setProfitModuleProtertyValue(profitModule, oldPro);
				
				modelDao.editUpdate(oldPro);
				
				modelDao.deleteProfitPerModuleByModelId(String.valueOf(modelId));;
				modelDao.deleteProfitRuleModuleByModelId(String.valueOf(modelId));;

				// 添加MCC类别
				if (profitModule.getProList() != null && profitModule.getProList().size() > 0) {
					List<ProfitRuleModule> proList = profitModule.getProList();
					for (ProfitRuleModule profitRule : proList) {
						
						if (profitRule.getId() != null) {

							// 如果是 云闪付，判断费率是否为0.28
							if ( 5 == profitRule.getId() ){
								double profitFee = profitRule.getProfitFee() ; 
								double profitSettleRate = profitRule.getProfitSettleRate() ; 
								double merchantMinFee = profitRule.getMerchantMinFee() ; 
								
								if ( profitFee != Constant.FEE_RATE ){
									throw new ServiceException("代理申请失败，云闪付 借记卡成本扣率 只能等于 " + Constant.FEE_RATE );
								}
								if ( profitSettleRate != Constant.FEE_RATE ){
									throw new ServiceException("代理申请失败，云闪付 贷记卡成本扣率 只能等于 " + Constant.FEE_RATE );
								}
								if ( merchantMinFee != Constant.FEE_RATE ){
									throw new ServiceException("代理申请失败，云闪付 贷记卡最低签扣 只能等于 " + Constant.FEE_RATE );
								}
							}
							// 如果是 银联扫码（非优惠），判断费率是否低于0.5025
							if ( 6 == profitRule.getId() ){
								double profitFee = profitRule.getProfitFee() ; 
								
								if ( profitFee < Constant.UNIONPAY_EVERYDAY_RATE ){
									throw new ServiceException("代理申请失败，银联扫码(非优惠) 成本扣率 不能低于 " + Constant.UNIONPAY_EVERYDAY_RATE );
								}
							}
							// 如果是 银联扫码（优惠），判断费率是否低于0.2
							if ( 7 == profitRule.getId() ){
								double profitFee = profitRule.getProfitFee() ; 
								
								if ( profitFee < Constant.UNIONPAY_UNEVERYDAY_RATE ){
									throw new ServiceException("代理申请失败，银联扫码(优惠) 成本扣率 不能低于 " + Constant.UNIONPAY_UNEVERYDAY_RATE );
								}
							}
							// 如果是 支付宝微信扫码，判断费率只能是 0.25-0.35 之间
							if ( 8 == profitRule.getId() ){
								double profitFee = profitRule.getProfitFee() ; 
								
								if ( profitFee < Constant.MIN_ALIPAY_RATE || profitFee > Constant.MAX_ALIPAY_RATE ){
									throw new ServiceException("代理申请失败，支付宝微信扫码 成本扣率 只能是 " + Constant.MIN_ALIPAY_RATE +"-" + Constant.MAX_ALIPAY_RATE + " 之间 " );
								}
							}
							
							profitRule.setDtCreate (new Date());
							profitRule.setDtLastmod (new Date());
							
							profitRule.setProfitModuleId(modelId);
							modelDao.editSave(profitRule);// add分润规则
						}
					}
				}
				
				// 添加代理商分润比例
				if (profitModule.getProfitPerList() != null && profitModule.getProfitPerList().size() > 0) {
					List<ProfitPercentModule> prList = profitModule.getProfitPerList();
					// 删除空数据
					prList = dealNull(prList);
					int i = 0;
					for (ProfitPercentModule profitPercent : prList) {

						profitPercent.setDtCreate (new Date());
						profitPercent.setDtLastmod (new Date());
					//	profitPercent.setAgent_id(op.getAccountNo());
						BigDecimal per = new BigDecimal(profitPercent.getPercent());
						profitPercent.setPercent(per.divide(new BigDecimal(100))
								.toString());

						if (i == 0) {
							profitPercent.setIsEnd("0");
						} else {
							profitPercent.setIsEnd("1");
						}
						if (i == prList.size() - 1) {
							profitPercent.setIsEnd("2");
						}
						profitPercent.setProfitModuleId(modelId);
						modelDao.editSave(profitPercent);
						i++;
					}

				}
				logger.info("操作员【" + logingOperators.getAccountNo()
						+ "】,修改代理商分润模板【" + profitModule.getId() + "-" + profitModule.getModuleName() + "】信息成功");
				modelDao.addSyslog(SysLogType.MODEL_PROFIT_MODIF.getCode(),
				SysLogType.MODEL_PROFIT_MODIF.getName(), logingOperators.getAccountNo(), "操作员"+ logingOperators.getAccountNo() 
								+ ",修改代理商分润模板【" + profitModule.getId() + "-" + profitModule.getModuleName() + "】信息成功");
				flag = true;
			} else {
				logger.info("######代理商分润模板修改失败,代理商分润模板不存在######");
			}
		} catch (DaoException e) {
			logger.error("######代理商分润模板修改失败######", e);
			throw new ServiceException("代理商分润模板修改失败!");
		}
		return flag;
	}

	/**
	 * 
	 * @param from
	 * @param target
	 */
	private void setProfitModuleProtertyValue(ProfitModule from, ProfitModule target) {
		target.setModuleName(from.getModuleName());
		target.setRemark(from.getRemark());
		target.setDtLastmod(new Date());
	}
	/**
	 * 删除操作员表，权限，分润规则
	 * 
	 * @param agentId
	 * @param accountNo
	 * @return
	 * @throws ServiceException
	 */
	@Override
	@Transactional(rollbackFor = { ServiceException.class })
	public boolean deleteProfitModule(ProfitModule profitModule, Operators oper)
			throws ServiceException {
		boolean flag = false;
		try {
			String accountNo = oper.getAccountNo();
			String moduleName = profitModule.getModuleName();
			String modelId = String.valueOf(profitModule.getId());
			
			// 通过 分润模板id 删除 分润规则模板
			modelDao.deleteProfitRuleModuleByModelId(modelId);
			// 通过 分润模板id 删除 分润比例模板
			modelDao.deleteProfitPerModuleByModelId(modelId);
			// 通过 分润模板id 删除 分润模板
			modelDao.deleteProfitModuleByModelId(modelId);

			logger.info("操作员【" + accountNo + "】删除了分润模板ID【" + modelId + "-" + moduleName + "】");
			modelDao.addSyslog(SysLogType.MODEL_PROFIT_DELETE.getCode(),
					SysLogType.MODEL_PROFIT_DELETE.getName(), accountNo, "操作员【"
							+ accountNo + "】删除了分润模板ID【" + modelId + "-" + moduleName + "】");
			flag = true;
		} catch (DaoException e) {
			logger.error("######代理商分润模板删除失败######", e);
			throw new ServiceException("代理商分润模板删除失败!");
		} 

		return flag;
	
	}


	@Override
	@Transactional(rollbackFor = { ServiceException.class })
	public boolean setDefaultProfitModule(String modelId,long agentId)
			throws ServiceException {
		boolean flag = false;
		
		try {
			// 查询当前默认的模板信息
			ProfitModule bean = modelDao.selDefProfitModuleByAgentId( agentId);
			
			if(null != bean){
				// 修改 默认模板 为普通模板
				modelDao.updateProfitModuleStatusById(String.valueOf(bean.getId()), ProfitModuleStatus.NO.getCode());
			}
			// 修改当前模板为默认模板
			modelDao.updateProfitModuleStatusById(modelId, ProfitModuleStatus.YES.getCode());
			flag = true;
		} catch (DaoException e) {
			logger.error("######修改代理商默认分润模板失败######", e);
			throw new ServiceException("修改代理商默认分润模板失败!");
		}
		return flag;
	}


	@Override
	public ProfitModule queryProfitModuleByModuleName(String moduleName) throws ServiceException {
		ProfitModule module = new ProfitModule();
		try {
			module = modelDao.queryProfitModuleByModuleName(moduleName);
		} catch (DaoException e) {
			logger.error("######查询代理商分润模板失败######", e);
			throw new ServiceException("查询代理商分润模板失败!");
		}
		
		return module;
	}
	
}
